Example from http://spatial.ly/2013/12/introduction-spatial-data-ggplot2/

# Read in the shapefile
library(rgdal)
sport <- rgdal::readOGR(dsn = "London", "london_sport")
## OGR data source with driver: ESRI Shapefile 
## Source: "London", layer: "london_sport"
## with 33 features
## It has 4 fields
# fixes an error in the london_sport file
proj4string(sport) <- CRS("+init=epsg:27700")
## Warning in `proj4string<-`(`*tmp*`, value = <S4 object of class structure("CRS", package = "sp")>): A new CRS was assigned to an object with an existing CRS:
## +proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +units=m +no_defs
## without reprojecting.
## For reprojection, use function spTransform in package rgdal

Convert to a form suited to ggplot:

sport.f <- ggplot2::fortify(sport, region = "ons_label")

Merge with the data we’re interested in displaying. sport@data is just a data table that happens to be included in the sport object. Let’s see if we can make it work with another data table.

sport.f <- merge(sport.f, sport@data, by.x = "id", by.y = "ons_label")

Make the map:

Map <- 
  ggplot(sport.f, 
         aes(x = long, y = lat, group = group, fill = Partic_Per)) + 
  geom_polygon() + 
  coord_equal() + 
  labs(x = "Easting (m)", y = "Northing (m)", fill = "% Sport Partic.") + 
  ggtitle("London Sports Participation")
Map + scale_fill_gradient(low = "white", high = "black")

Base Maps

Reset the coordinate system to degrees lat and long

sport.wgs84 <- spTransform(sport, CRS("+init=epsg:4326"))

Find the bounding box and scale around that

b <- bbox(sport.wgs84)
b[1, ] <- (b[1, ] - mean(b[1, ])) * 1.05 + mean(b[1, ])
b[2, ] <- (b[2, ] - mean(b[2, ])) * 1.05 + mean(b[2, ])
# scale longitude and latitude (increase bb by 5% for plot) replace 1.05
# with 1.xx for an xx% increase in the plot size

Get the tiles

lnd.b1 <- ggmap(get_map(location = b))
## Warning: bounding box given to google - spatial extent only approximate.
## converting bounding box to center/zoom specification. (experimental)
## Map from URL : http://maps.googleapis.com/maps/api/staticmap?center=51.489304,-0.088233&zoom=10&size=640x640&scale=2&maptype=terrain&language=en-EN&sensor=false

Merge the shape file with the data

sport.wgs84.f <- fortify(sport.wgs84, region = "ons_label")
sport.wgs84.f <- merge(sport.wgs84.f, sport.wgs84@data, by.x = "id", by.y = "ons_label")
lnd.b1 + 
  geom_polygon(data = sport.wgs84.f, 
               aes(x = long, y = lat, group = group, fill = Partic_Per), 
    alpha = 0.5)

World Map

Got shapefile from Geocommons, but a more extensive set is from the CDC

world <- rgdal::readOGR(dsn = "WorldCountries", "world_country_admin_boundary_shapefile_with_fips_codes")
## OGR data source with driver: ESRI Shapefile 
## Source: "WorldCountries", layer: "world_country_admin_boundary_shapefile_with_fips_codes"
## with 252 features
## It has 2 fields

Convert to a form suited to ggplot:

world.f <- ggplot2::fortify(world, region="CNTRY_NAME")

The region = argument is set to one of the variable names in the .dbf file that comes with the shape files. You can read this with ….

FIPS <- foreign::read.dbf(
  file = "WorldCountries/world_country_admin_boundary_shapefile_with_fips_codes.dbf",
  as.is = TRUE)

Making an example:

library(DCF)
## Loading required package: dplyr
## 
## Attaching package: 'dplyr'
## 
## The following objects are masked from 'package:rgeos':
## 
##     intersect, setdiff, union
## 
## The following object is masked from 'package:stats':
## 
##     filter
## 
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
## 
## Loading required package: rworldmap
## ### Welcome to rworldmap ###
## For a short introduction type :   vignette('rworldmap')
## Loading required package: RCurl
## Loading required package: bitops
## Loading required package: igraph
## Loading required package: NHANES
## Loading required package: mosaicData
ours <- CountryData%>% select(id=country, fert)
ggplot(world.f, aes(x=long, y=lat, group=group)) + geom_path()

all <- left_join(world.f, ours)
## Joining by: "id"
ggplot(all, aes(x=long, y=lat, fill=fert, group=group)) + geom_polygon()

ggplot() + geom_map(data=all, aes(fill=fert, x=long, y=lat, map_id=id), map=world.f)

Another approach

library(ggmap)
library(mapproj)
map <- get_map(location = 'minnesota', maptype="hybrid",
               zoom = 9)
## Map from URL : http://maps.googleapis.com/maps/api/staticmap?center=minnesota&zoom=9&size=640x640&scale=2&maptype=hybrid&language=en-EN&sensor=false
## Information from URL : http://maps.googleapis.com/maps/api/geocode/json?address=minnesota&sensor=false
ggmap(map)

Other locations: state names, continents, countries, … or latitude/longitude pairs.